---
title: GitHub Actions
description: Learn how to use GitHub Actions with Turborepo.
---

import { PackageManagerTabs, Tab } from '#/components/tabs';
import { Steps, Step } from '#/components/steps';

The following example shows how to use Turborepo with [GitHub Actions](https://github.com/features/actions).

For a given root `package.json`:

```json title="./package.json"
{
  "name": "my-turborepo",
  "scripts": {
    "build": "turbo run build",
    "test": "turbo run test"
  },
  "devDependencies": {
    "turbo": "latest"
  }
}
```

And a `turbo.json`:

```json title="./turbo.json"
{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "outputs": [".next/**", "!.next/cache/**", "other-output-dirs/**"],
      "dependsOn": ["^build"]
    },
    "test": {
      "dependsOn": ["^build"]
    }
  }
}
```

Create a file called `.github/workflows/ci.yml` in your repository with the following contents:

<PackageManagerTabs>
  <Tab>

    ```yaml title=".github/workflows/ci.yml"
    name: CI

    on:
      push:
        branches: ["main"]
      pull_request:
        types: [opened, synchronize]

    jobs:
      build:
        name: Build and Test
        timeout-minutes: 15
        runs-on: ubuntu-latest
        # To use Remote Caching, uncomment the next lines and follow the steps below.
        # env:
        #  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
        #  TURBO_TEAM: ${{ vars.TURBO_TEAM }}
        #  TURBO_REMOTE_ONLY: true

        steps:
          - name: Check out code
            uses: actions/checkout@v4
            with:
              fetch-depth: 2

          - name: Setup Node.js environment
            uses: actions/setup-node@v4
            with:
              node-version: 20
              cache: 'npm'

          - name: Install dependencies
            run: npm install

          - name: Build
            run: npm run build

          - name: Test
            run: npm run test
    ```

  </Tab>
  <Tab>

    ```yaml title=".github/workflows/ci.yml"
    name: CI

    on:
      push:
        branches: ["main"]
      pull_request:
        types: [opened, synchronize]

    jobs:
      build:
        name: Build and Test
        timeout-minutes: 15
        runs-on: ubuntu-latest
        # To use Remote Caching, uncomment the next lines and follow the steps below.
        # env:
        #  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
        #  TURBO_TEAM: ${{ vars.TURBO_TEAM }}

        steps:
          - name: Check out code
            uses: actions/checkout@v4
            with:
              fetch-depth: 2

          - name: Setup Node.js environment
            uses: actions/setup-node@v4
            with:
              node-version: 20
              cache: 'yarn'

          - name: Install dependencies
            run: yarn

          - name: Build
            run: yarn build

          - name: Test
            run: yarn test
    ```

  </Tab>
  <Tab>
    ```yaml title=".github/workflows/ci.yml"
    name: CI

    on:
      push:
        branches: ["main"]
      pull_request:
        types: [opened, synchronize]

    jobs:
      build:
        name: Build and Test
        timeout-minutes: 15
        runs-on: ubuntu-latest
        # To use Remote Caching, uncomment the next lines and follow the steps below.
        # env:
        #  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
        #  TURBO_TEAM: ${{ vars.TURBO_TEAM }}

        steps:
          - name: Check out code
            uses: actions/checkout@v4
            with:
              fetch-depth: 2

          - uses: pnpm/action-setup@v3
            with:
              version: 8

          - name: Setup Node.js environment
            uses: actions/setup-node@v4
            with:
              node-version: 20
              cache: 'pnpm'

          - name: Install dependencies
            run: pnpm install

          - name: Build
            run: pnpm build

          - name: Test
            run: pnpm test
    ```

  </Tab>
</PackageManagerTabs>

## Remote Caching

To use Remote Caching with GitHub Actions, add the following environment variables to your GitHub Actions workflow
to make them available to your `turbo` commands.

- `TURBO_TOKEN` - The Bearer token to access the Remote Cache
- `TURBO_TEAM` - The account to which the monorepo belongs

To use Remote Caching, retrieve the team and token for the Remote Cache for your provider. In this example, we'll use [Vercel Remote Cache](https://vercel.com/docs/monorepos/remote-caching).

<Steps>
<Step>
Create a Scoped Access Token to your account in the [Vercel Dashboard](https://vercel.com/account/tokens)

![Vercel Access Tokens](/images/docs/vercel-create-token.png)

Copy the value to a safe place. You'll need it in a moment.

</Step>
<Step>
Go to your GitHub repository settings and click on the **Secrets** and then **Actions** tab. Create a new secret called `TURBO_TOKEN` and enter the value of your Scoped Access Token.

![GitHub Secrets](/images/docs/github-actions-secrets.png)
![GitHub Secrets Create](/images/docs/github-actions-create-secret.png)

</Step>

<Step>
Create a new repository variable (click the **Variables** tab) called `TURBO_TEAM` and enter the value of your team's Vercel URL _without_ the `vercel.com/`.
   Using a repository variable rather than a secret will keep GitHub Actions from censoring your team name in log output.

![GitHub Repository Variables](/images/docs/vercel-team-repo-var.png)

Your Team URL can be found inside your team's general project settings from the dashboard. If you're using a Hobby Plan, you can use your username. Your username can be found in your [Vercel Personal Account Settings](https://vercel.com/account)

![Vercel Account Slug](/images/docs/vercel-slug.png)

</Step>
<Step>
At the top of your GitHub Actions workflow, provide the following environment variables to jobs that use `turbo`:

```yaml title=".github/workflows/ci.yml"
# ...

jobs:
  build:
    name: Build and Test
    timeout-minutes: 15
    runs-on: ubuntu-latest
    # To use Turborepo Remote Caching, set the following environment variables for the job.
    env:
      TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} // [!code highlight]
      TURBO_TEAM: ${{ vars.TURBO_TEAM }} // [!code highlight]

    steps:
      - name: Check out code
        uses: actions/checkout@v4
        with:
          fetch-depth: 2
    # ...
```

</Step>
</Steps>

## Caching with GitHub actions/cache

The following steps exemplify how you could use [actions/cache](https://github.com/actions/cache) to cache your monorepo artifacts on GitHub.

<Steps>
<Step>
Supply a package.json script that will run tasks using Turbo.

Example `package.json` with a `build` script:

```json title="./package.json"
{
  "name": "my-turborepo",
  "scripts": {
    "build": "turbo run build"
  },
  "devDependencies": {
    "turbo": "1.2.5"
  }
}
```

</Step>
<Step>
Configure your GitHub pipeline with a step which utilizes the `actions/cache@v4` action before the build steps of your CI file.

- Make sure that the `path` attribute set within the `actions/cache` action matches the output location above. In the example below, `path` was set to `.turbo`.
- State the cache key for the current run under the `key` attribute. In the example below, we used a combination of the runner os and GitHub sha as the cache key.
- State the desired cache prefix pattern under the `restore-keys` attribute. Make sure this pattern will remain valid for future ci runs. In the example below, we used the `${{ runner.os }}-turbo-` as the cache key prefix pattern to search against. This allows us to hit the cache on any subsequent ci runs despite `github.sha` changing.

Example `ci` yaml with `.turbo` as chosen cache folder:

```yaml title=".github/workflows/ci.yml"
  jobs:
    build:
      runs-on: ubuntu-latest
      steps:
        - name: Check out code
          uses: actions/checkout@v4

        - name: Cache turbo build setup // [!code highlight]
          uses: actions/cache@v4 // [!code highlight]
          with: // [!code highlight]
            path: .turbo // [!code highlight]
            key: ${{ runner.os }}-turbo-${{ github.sha }} // [!code highlight]
            restore-keys: | // [!code highlight]
              ${{ runner.os }}-turbo- // [!code highlight]

        - name: Setup Node.js environment
          uses: actions/setup-node@v4
          with:
            node-version: 20
            cache: 'npm'

        - name: Install dependencies
          run: npm install

        - name: Build
          run: npm run build
```

</Step>
</Steps>
